package org.xi2p;

import java.io.PrintWriter;
import java.util.ArrayList;

public class BadPainter{
    ArrayList<Note> notes = new ArrayList<>();
    PrintWriter printWriter;
    int FADE_DURATION = 200;

    public BadPainter(PrintWriter printWriter) {
        this.printWriter = printWriter;
    }

    public void addBad(Note note){
        notes.add(note);
    }

    public void writeAndFlush(long current){
        notes.removeIf((note) -> current - note.lastEvalTime > FADE_DURATION);
        for (Note note : notes){
            if (note.type == 1){
                double x1, y1, x2, y2, x3, y3, x4, y4;
                x1 = note.xInSurface + core.NOTE_R * Math.cos(Math.toRadians(note.judgeline.angle + core.NOTE_THETA));
                y1 = note.yInSurface - core.NOTE_R * Math.sin(Math.toRadians(note.judgeline.angle + core.NOTE_THETA));

                x2 = note.xInSurface + core.NOTE_R * Math.cos(Math.toRadians(note.judgeline.angle + 180 - core.NOTE_THETA));
                y2 = note.yInSurface - core.NOTE_R * Math.sin(Math.toRadians(note.judgeline.angle + 180 - core.NOTE_THETA));

                x3 = note.xInSurface + core.NOTE_R * Math.cos(Math.toRadians(note.judgeline.angle - 180 + core.NOTE_THETA));
                y3 = note.yInSurface - core.NOTE_R * Math.sin(Math.toRadians(note.judgeline.angle - 180 + core.NOTE_THETA));

                x4 = note.xInSurface + core.NOTE_R * Math.cos(Math.toRadians(note.judgeline.angle - core.NOTE_THETA));
                y4 = note.yInSurface - core.NOTE_R * Math.sin(Math.toRadians(note.judgeline.angle - core.NOTE_THETA));

                double alpha = 255.0 * (1.0 - 1.0 * (current - note.lastEvalTime) / FADE_DURATION);

                printWriter.write("%d %.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f 255 40 90 %.2f|".formatted(
                        1, x1, y1, x2, y2, x3, y3, x4, y4, alpha
                ));
            } else {
                Hold hold = (Hold) note;
                double _length = hold.length * (hold.above ? 1 : -1);

                double x1, y1, x2, y2, x3, y3, x4, y4;
                {
                    x1 = hold.xInSurface + core.NOTE_R * Math.cos(Math.toRadians(hold.judgeline.angle + core.NOTE_THETA));
                    y1 = hold.yInSurface - core.NOTE_R * Math.sin(Math.toRadians(hold.judgeline.angle + core.NOTE_THETA));

                    x2 = hold.xInSurface + core.NOTE_R * Math.cos(Math.toRadians(hold.judgeline.angle + 180 - core.NOTE_THETA));
                    y2 = hold.yInSurface - core.NOTE_R * Math.sin(Math.toRadians(hold.judgeline.angle + 180 - core.NOTE_THETA));

                    x3 = hold.xInSurface + core.NOTE_R * Math.cos(Math.toRadians(hold.judgeline.angle - 180 + core.NOTE_THETA));
                    y3 = hold.yInSurface - core.NOTE_R * Math.sin(Math.toRadians(hold.judgeline.angle - 180 + core.NOTE_THETA));

                    x4 = hold.xInSurface + core.NOTE_R * Math.cos(Math.toRadians(hold.judgeline.angle - core.NOTE_THETA));
                    y4 = hold.yInSurface - core.NOTE_R * Math.sin(Math.toRadians(hold.judgeline.angle - core.NOTE_THETA));
                }

                double _angle = Math.toDegrees(Math.atan(_length / (core.BAR_WIDTH / 2) * 2));
                double _angle1 = Math.toRadians(hold.judgeline.angle + _angle);
                double _angle2 = Math.toRadians(180 + hold.judgeline.angle - _angle);
                double _r = Math.sqrt((_length * _length + ((core.BAR_WIDTH / 2) / 2) * ((core.BAR_WIDTH / 2) / 2)));
                double x5, x6, x7, x8, y5, y6, y7, y8;
                x5 = hold.xInSurface + (core.BAR_WIDTH / 2) / 2 * Math.cos(Math.toRadians(hold.judgeline.angle));
                y5 = hold.yInSurface - (core.BAR_WIDTH / 2) / 2 * Math.sin(Math.toRadians(hold.judgeline.angle));
                x6 = hold.xInSurface - (core.BAR_WIDTH / 2) / 2 * Math.cos(Math.toRadians(hold.judgeline.angle));
                y6 = hold.yInSurface + (core.BAR_WIDTH / 2) / 2 * Math.sin(Math.toRadians(hold.judgeline.angle));
                x7 = hold.xInSurface + _r * Math.cos(_angle2);
                y7 = hold.yInSurface - _r * Math.sin(_angle2);
                x8 = hold.xInSurface + _r * Math.cos(_angle1);
                y8 = hold.yInSurface - _r * Math.sin(_angle1);

                double alpha = 255.0 * (1.0 - 1.0 * (current - note.lastEvalTime) / FADE_DURATION);

                printWriter.write("%d %.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f 255 40 90 %.2f|".formatted(
                        4, x1, y1, x2, y2, x3, y3, x4, y4, x5, x6, x7, x8, y5, y6, y7, y8, alpha
                ));
            }
        }
        printWriter.write('$');
        printWriter.flush();
    }
}